from com.atzl.interaction.WindowMessage import MessageWindow
from com.atzl.ui.WindowMonBillUI import Ui_MainWindow as ui1
import sys
from PyQt5 import QtCore
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtCore import QPropertyAnimation, QRect, QEasingCurve, QObject
from com.atzl.common.Datas import MessagesData
from com.atzl.common.Win import Windows
from com.atzl.common.ActionStates import ActionStates
from com.atzl.common.StatusCode import StatusCode
from com.atzl.functions.accounting.func.Logs import CheckLogs
from com.atzl.functions.accounting.func.SetTlementObj import DataCleansing

# 制作账单窗口交互
class BillWindow(QMainWindow, CheckLogs):  # 继承:QMainWindow, CheckLogs
    def __init__(self):
        QMainWindow.__init__(self)
        # 设置为全局小部件
        self.ui = ui1()
        self.data = DataCleansing()
        self.work = work_thread()
        self.message = MessageWindow()
        self.m_flag = False
        self.ui.setupUi(self)
        global widgets
        widgets = self.ui
        global dataw
        dataw = self.data

        widgets.pushButton_7.clicked.connect(self.roll_back_navigation)  # 返回导航页
        widgets.pushButton.clicked.connect(self.work.start)  # 开启线程
        widgets.pushButton.setShortcut('ctrl+s')  # 设置按钮快捷键
        widgets.pushButton_3.clicked.connect(self.open_the_files)  # 打开文件目录
        self.work.select_obj_end.connect(self.obj_end)  # 触发结束线程信号
        self.work.select_obj_start.connect(self.obj_start)  # 触发启动线程信号
        self.work.select_obj_notdata.connect(self.obj_notdata)  # 触发启动线程信号
        self.work.select_obj_error.connect(self.obj_error)  # 触发启动线程信号
        widgets.pushButton_2.clicked.connect(self.stop_work)  # 清空客户查询框内容
        widgets.pushButton_2.clicked.connect(widgets.textBrowser.clear)
        widgets.pushButton_2.clicked.connect(self.stop_workThread)  # 中断线程
        widgets.pushButton_4.clicked.connect(self.esceap)  # 关闭应用
        widgets.pushButton_5.clicked.connect(self.showMinimized)  # 窗口最小化
        widgets.pushButton_6.clicked.connect(self.updata_name)
        widgets.textBrowser.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)  # 隐藏工具条
        widgets.textEdit.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)  # 隐藏工具条



        sys.stdout = Signal()
        sys.stdout.text_update.connect(self.updatetext)


        # 设置控件的几何属性
        self.px = widgets.label.x() + 500
        self.py = widgets.label.y()
        self.pw = widgets.label.width()
        self.ph = widgets.label.height()
        self.pe = widgets.label.geometry()

        # 同上
        self.px1 = widgets.textBrowser.x() + 180
        self.py1 = widgets.textBrowser.y()
        self.pw1 = widgets.textBrowser.width()
        self.ph1 = widgets.textBrowser.height()
        self.pe1 = widgets.textBrowser.geometry()

        widgets.label.hide()  # 隐藏控件


    def get_tablesname(self):
        if MessagesData.ORIGINAL_TABLESNAME == []:
            self.tablesname = self.data.get_mydataname()  # 获取表名称
            # 判断是否与数据库建立连接
            if self.tablesname == StatusCode.BREAK_DATABASE:  # 失去连接
                self.to_message(StatusCode.BREAK_DATABASE)  # 弹出消息提示框,提示 与数据库断开连接
            elif self.tablesname == StatusCode.CONNECTDATABASE_PARAMETER:  # 连接数据库参数异常
                self.to_message(StatusCode.CONNECTDATABASE_PARAMETER)  # 弹出消息提示框,提示 连接数据库参数异常
            elif self.tablesname == StatusCode.UNKONWN_ERROR:  # 未知异常
                self.to_message(StatusCode.UNKONWN_ERROR)  # 弹出消息提示框,提示 未知异常
            else:  # 正常连接
                for j in self.tablesname:  # 遍历表名称
                    widgets.comboBox.addItem(j)
                    MessagesData.ORIGINAL_TABLESNAME.append(j)
        else:
            for j in MessagesData.ORIGINAL_TABLESNAME:
                widgets.comboBox.addItem(j)


    # 中断线程
    def stop_workThread(self):
        widgets.pushButton.show()  # 显示查询按钮
        widgets.gif.stop()  # 暂停播放动图
        self.to_message(StatusCode.MAKE_FINISH)  # 消息提示
        self.anim0 = QPropertyAnimation(widgets.label, b"geometry")  # 设置动画对象
        self.anim0.setDuration(850)  # 设置动画时长
        self.anim0.setStartValue(self.pe)  # 设置初始属性
        self.anim0.setEndValue(QRect(self.px,
                                     self.py,
                                     self.pw,
                                     self.ph))  # 设置结束属性
        self.anim0.setEasingCurve(QEasingCurve.InQuad)
        self.anim0.start()  # 开始动画

        self.anim1 = QPropertyAnimation(widgets.textBrowser, b"geometry")  # 设置动画对象
        self.anim1.setDuration(850)  # 设置动画时长
        self.anim1.setStartValue(QRect(self.px1,
                                       self.py1,
                                       self.pw1,
                                       self.ph1))  # 设置初始属性
        self.anim1.setEndValue(self.pe1)  # 设置结束属性
        self.anim1.setEasingCurve(QEasingCurve.InQuad)
        self.anim1.start()  # 开始动画
        self.work.terminate()  # 中断线程

    # 打卡文件目录
    def open_the_files(self):
        # 判断文件目录是否打开成功
        if self.data.open_files() is False:  # 返回False提示找不到文件路径
            self.to_message(StatusCode.MISSING_DIRPATH)  # 提示消息
            self.logs_in(ActionStates.HINTDONTHAVEDIR)  # 回传用户行为
        else:  # 返回True不做提示
            self.logs_in(ActionStates.OPENDEPOSITDIR)  # 回传用户行为



    # 设置线程启动时界面交互
    def obj_start(self):
        widgets.pushButton.hide()  # 隐藏查询按钮
        widgets.gif.start()  # 开始播放动图
        widgets.label.show()  # 显示动图控件
        self.anim0 = QPropertyAnimation(widgets.label, b"geometry")  # 设置动画对象
        self.anim0.setDuration(650)  # 设置动画时长
        self.anim0.setStartValue(QRect(self.px,
                                       self.py,
                                       self.pw,
                                       self.ph))  # 设置初始属性
        self.anim0.setEndValue(self.pe)  # 设置结束属性
        self.anim0.setEasingCurve(QEasingCurve.InQuad)
        self.anim0.start()  # 开始动画

        self.anim1 = QPropertyAnimation(widgets.textBrowser, b"geometry")  # 设置动画对象
        self.anim1.setDuration(650)  # 设置动画时长
        self.anim1.setEndValue(QRect(self.px1,
                                     self.py1,
                                     self.pw1,
                                     self.ph1))  # 设置结束属性
        self.anim1.setStartValue(self.pe1)  # 设置初始属性
        self.anim1.setEasingCurve(QEasingCurve.InQuad)
        self.anim1.start()  # 开始动画

        self.logs_in(ActionStates.STARTCREATERBILLBUTTON)  # 回传用户行为



    # 设置线程结束时界面交互
    def obj_end(self):
        widgets.pushButton.show()  # 显示查询按钮

        widgets.gif.stop()  # 暂停播放动图

        self.to_message(StatusCode.SUBTASK_FINISH)  # 消息提示
        self.anim0 = QPropertyAnimation(widgets.label, b"geometry")  # 设置动画对象
        self.anim0.setDuration(850)  # 设置动画时长
        self.anim0.setEndValue(QRect(self.px,
                                     self.py,
                                     self.pw,
                                     self.ph))  # 设置结束属性
        self.anim0.setStartValue(self.pe)  # 设置初始属性
        self.anim0.setEasingCurve(QEasingCurve.InQuad)
        self.anim0.start()  # 开始动画

        self.anim1 = QPropertyAnimation(widgets.textBrowser, b"geometry")  # 设置动画对象
        self.anim1.setDuration(850)  # 设置动画时长
        self.anim1.setStartValue(QRect(self.px1,
                                       self.py1,
                                       self.pw1,
                                       self.ph1))  # 设置初始属性
        self.anim1.setEndValue(self.pe1)  # 设置结束属性
        self.anim1.setEasingCurve(QEasingCurve.InQuad)
        self.anim1.start()  # 开始动画
        self.logs_in(ActionStates.NEDCREATERBILLBUTTON)  # 回传用户行为


    def obj_notdata(self):
        self.to_message(StatusCode.NOTHINGNESS_DATA)
        self.logs_in(StatusCode.NOTHINGNESS_DATA)  # 回传用户行为

    def obj_error(self):
        self.to_message(StatusCode.UNKONWN_ERROR)
        self.logs_in(StatusCode.UNKONWN_ERROR)  # 回传用户行为


    def updatetext(self, text):
        try:
            cursor = self.ui.textBrowser.textCursor()
            cursor.movePosition(QTextCursor.End)
            self.ui.textBrowser.append(text)
            self.ui.textBrowser.setTextCursor(cursor)
            self.ui.textBrowser.ensureCursorVisible()
        except Exception:
            pass




    def slot_max_or_recv(self):
        if self.isMaximized():
            self.showNormal()
        else:
            self.showMaximized()



    def updata_name(self):
        widgets.comboBox.clear()
        widgets.comboBox.addItem("")
        widgets.comboBox.setItemText(0, "--选择需计算的表--")
        for j in self.data.get_mydataname():
            widgets.comboBox.addItem(j)


    # 重写鼠标单击事件
    def mousePressEvent(self, event):
        if event.button() == QtCore.Qt.LeftButton:
            self.m_flag = True
            self.m_Position = event.globalPos() - self.pos()  # 获取鼠标相对窗口的位置
            event.accept()
            self.setCursor(QCursor(QtCore.Qt.OpenHandCursor))  # 更改鼠标图标


    # 重写鼠标移动事件
    def mouseMoveEvent(self, QMouseEvent):
        if QtCore.Qt.LeftButton and self.m_flag:
            self.move(QMouseEvent.globalPos() - self.m_Position)  # 更改窗口位置
            QMouseEvent.accept()


    # 重写鼠标释放事件
    def mouseReleaseEvent(self, QMouseEvent):
        self.m_flag = False
        self.setCursor(QCursor(QtCore.Qt.ArrowCursor))


    # 返回导航页面
    def roll_back_navigation(self):
        widgets.comboBox.clear()
        widgets.comboBox.addItem('--选择需计算的表--')
        self.hide()  # 隐藏账单制作页面
        Windows.NAVIGATION_WIN.show()  # 显示导航页
        Windows.NAVIGATION_WIN.show_anim()  # 启动导航页出场动画
        self.logs_in(ActionStates.ROLLBACKNAVIGATION)  # 回传用户行为


    # 关闭应用程序
    def esceap(self):
        self.logs_in(ActionStates.CLOSEAPPLICATION)  # 回传用户行为
        self.work.terminate()  # 中断线程
        self.close()  # 关闭应用程序


    # 清空客户查询框内容
    def stop_work(self):
        widgets.gif.stop()  # 暂停播放动图
        widgets.textEdit.clear()  # 清空客户查询框内容
        self.logs_in(ActionStates.BREAKCREATERBILL)  # 回传用户行为


    # 弹出消息提示框
    def to_message(self, text):
        Windows.MESSAGE_WIN.set_message(text)  # 设置提示内容并弹出提示框


    # 设置出场动画
    def show_anim(self):
        self.anim0 = QPropertyAnimation(self, b"windowOpacity")  # 设置动画对象
        self.anim0.setDuration(150)  # 设置动画时长
        self.anim0.setStartValue(0)  # 设置初始属性,0为完全透明
        self.anim0.setEndValue(1)  # 设置结束属性,1.0为不透明
        self.anim0.start()  # 开始动画



# 创建子线程
class work_thread(QThread):  # 继承:QThread


    select_obj_end = pyqtSignal()  # 创建线程结束信号对象
    select_obj_start = pyqtSignal()  # 创建线程启动信号对象
    select_obj_notdata = pyqtSignal()  # 查询完数据库,全无相关数据时信号对象
    select_obj_error = pyqtSignal()  # 未知错误信号对象

    def __init__(self):
        super().__init__()

    # 重写run方法
    def run(self):
        self.select_obj_start.emit()  # 发射启动信号

        dispose_data = dataw.select_settlementobj(widgets.textEdit.toPlainText().splitlines(False),
                                                  widgets.comboBox.currentText())
        # 判断账单制作情况
        if dispose_data == StatusCode.SUBTASK_FINISH:  # 正常结束时
            self.select_obj_end.emit()  # 发射正常结束信号
        elif dispose_data == StatusCode.NOTHINGNESS_DATA:  # 无相关数据时
            self.select_obj_notdata.emit()  # 发射无相关数据信号
        elif dispose_data == StatusCode.UNKONWN_ERROR:
            self.select_obj_error.emit()  # 发射未知错误信号


# 自定义信号类
class Signal(QObject):  # 继承:QObject

    text_update = pyqtSignal(str)  # 定义文本变化信号

    def write(self, text):
        self.text_update.emit(str(text))  # 发射文本改变信号并将传入文本值
        QApplication.processEvents()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = BillWindow()
    ui = ui1()
    window.show()
    sys.exit(app.exec_())